// 集合管理器

import { BaseManager } from '../core/BaseManager';
import { RedisClient } from '../core/RedisClient';
import { KeyGenerator } from '../utils/keyGenerator';

export interface ScoredMember {
  member: string;
  score: number;
}

export interface SetStats {
  size: number;
  type: 'set' | 'zset';
  memoryUsage: number | undefined;
}

export interface SetOperationResult {
  members: string[];
  count: number;
}

export class SetManager extends BaseManager {
  constructor(client: RedisClient) {
    super(client, new KeyGenerator({ prefix: 'set' }));
  }

  // ========== 普通集合操作 ==========

  /**
   * 添加成员到集合
   */
  async add(key: string, ...members: string[]): Promise<number> {
    this.validateRequired({ key, members });

    const setKey = this.keyGenerator.set(key);
    return this.execute<number>('sadd', setKey, ...members);
  }

  /**
   * 从集合移除成员
   */
  async remove(key: string, ...members: string[]): Promise<number> {
    this.validateRequired({ key, members });

    const setKey = this.keyGenerator.set(key);
    return this.execute<number>('srem', setKey, ...members);
  }

  /**
   * 检查成员是否在集合中
   */
  async isMember(key: string, member: string): Promise<boolean> {
    this.validateRequired({ key, member });

    const setKey = this.keyGenerator.set(key);
    const result = await this.execute<number>('sismember', setKey, member);
    return result === 1;
  }

  /**
   * 获取集合所有成员
   */
  async getMembers(key: string): Promise<string[]> {
    this.validateRequired({ key });

    const setKey = this.keyGenerator.set(key);
    return this.execute<string[]>('smembers', setKey);
  }

  /**
   * 获取集合大小
   */
  async size(key: string): Promise<number> {
    this.validateRequired({ key });

    const setKey = this.keyGenerator.set(key);
    return this.execute<number>('scard', setKey);
  }

  /**
   * 随机获取成员
   */
  async randomMember(key: string, count?: number): Promise<string | string[]> {
    this.validateRequired({ key });

    const setKey = this.keyGenerator.set(key);

    if (count === undefined) {
      return this.execute<string>('srandmember', setKey);
    } else {
      return this.execute<string[]>('srandmember', setKey, count);
    }
  }

  /**
   * 随机移除并返回成员
   */
  async pop(key: string, count?: number): Promise<string | string[]> {
    this.validateRequired({ key });

    const setKey = this.keyGenerator.set(key);

    if (count === undefined) {
      return this.execute<string>('spop', setKey);
    } else {
      return this.execute<string[]>('spop', setKey, count);
    }
  }

  // ========== 集合运算 ==========

  /**
   * 集合并集
   */
  async union(...keys: string[]): Promise<string[]> {
    this.validateRequired({ keys });

    const setKeys = keys.map(key => this.keyGenerator.set(key));
    return this.execute<string[]>('sunion', ...setKeys);
  }

  /**
   * 集合并集并存储
   */
  async unionStore(destination: string, ...keys: string[]): Promise<number> {
    this.validateRequired({ destination, keys });

    const destKey = this.keyGenerator.set(destination);
    const setKeys = keys.map(key => this.keyGenerator.set(key));
    return this.execute<number>('sunionstore', destKey, ...setKeys);
  }

  /**
   * 集合交集
   */
  async intersection(...keys: string[]): Promise<string[]> {
    this.validateRequired({ keys });

    const setKeys = keys.map(key => this.keyGenerator.set(key));
    return this.execute<string[]>('sinter', ...setKeys);
  }

  /**
   * 集合交集并存储
   */
  async intersectionStore(destination: string, ...keys: string[]): Promise<number> {
    this.validateRequired({ destination, keys });

    const destKey = this.keyGenerator.set(destination);
    const setKeys = keys.map(key => this.keyGenerator.set(key));
    return this.execute<number>('sinterstore', destKey, ...setKeys);
  }

  /**
   * 集合差集
   */
  async difference(key1: string, key2: string): Promise<string[]> {
    this.validateRequired({ key1, key2 });

    const setKey1 = this.keyGenerator.set(key1);
    const setKey2 = this.keyGenerator.set(key2);
    return this.execute<string[]>('sdiff', setKey1, setKey2);
  }

  /**
   * 集合差集并存储
   */
  async differenceStore(destination: string, key1: string, key2: string): Promise<number> {
    this.validateRequired({ destination, key1, key2 });

    const destKey = this.keyGenerator.set(destination);
    const setKey1 = this.keyGenerator.set(key1);
    const setKey2 = this.keyGenerator.set(key2);
    return this.execute<number>('sdiffstore', destKey, setKey1, setKey2);
  }

  // ========== 有序集合操作 ==========

  /**
   * 添加成员到有序集合
   */
  async addScored(key: string, score: number, member: string): Promise<number>;
  async addScored(key: string, ...scoredMembers: Array<number | string>): Promise<number>;
  async addScored(key: string, ...args: Array<number | string>): Promise<number> {
    this.validateRequired({ key, args });

    const zsetKey = this.keyGenerator.set(key, 'zset');
    return this.execute<number>('zadd', zsetKey, ...args);
  }

  /**
   * 移除有序集合成员
   */
  async removeScored(key: string, ...members: string[]): Promise<number> {
    this.validateRequired({ key, members });

    const zsetKey = this.keyGenerator.set(key, 'zset');
    return this.execute<number>('zrem', zsetKey, ...members);
  }

  /**
   * 获取成员分数
   */
  async getScore(key: string, member: string): Promise<number | null> {
    this.validateRequired({ key, member });

    const zsetKey = this.keyGenerator.set(key, 'zset');
    const score = await this.execute<string | null>('zscore', zsetKey, member);
    return score ? parseFloat(score) : null;
  }

  /**
   * 增加成员分数
   */
  async incrementScore(key: string, member: string, increment: number): Promise<number> {
    this.validateRequired({ key, member });
    this.validateNumber(increment, 'increment');

    const zsetKey = this.keyGenerator.set(key, 'zset');
    const result = await this.execute<string>('zincrby', zsetKey, increment, member);
    return parseFloat(result);
  }

  /**
   * 获取成员排名
   */
  async getRank(key: string, member: string, reverse: boolean = false): Promise<number | null> {
    this.validateRequired({ key, member });

    const zsetKey = this.keyGenerator.set(key, 'zset');
    const command = reverse ? 'zrevrank' : 'zrank';
    const rank = await this.execute<number | null>(command, zsetKey, member);
    return rank;
  }

  /**
   * 按排名获取范围
   */
  async getRange(
    key: string,
    start: number,
    stop: number,
    withScores: boolean = false,
    reverse: boolean = false
  ): Promise<string[] | ScoredMember[]> {
    this.validateRequired({ key });
    this.validateNumber(start, 'start');
    this.validateNumber(stop, 'stop');

    const zsetKey = this.keyGenerator.set(key, 'zset');
    const command = reverse ? 'zrevrange' : 'zrange';
    const args = [zsetKey, start, stop];

    if (withScores) {
      args.push('WITHSCORES');
    }

    const result = await this.execute<string[]>(command, ...args);

    if (withScores) {
      const scoredMembers: ScoredMember[] = [];
      for (let i = 0; i < result.length; i += 2) {
        const member = result[i];
        const scoreStr = result[i + 1];
        if (member && scoreStr) {
          scoredMembers.push({
            member,
            score: parseFloat(scoreStr),
          });
        }
      }
      return scoredMembers;
    }

    return result;
  }

  /**
   * 按分数获取范围
   */
  async getRangeByScore(
    key: string,
    min: number | string,
    max: number | string,
    withScores: boolean = false,
    limit?: { offset: number; count: number }
  ): Promise<string[] | ScoredMember[]> {
    this.validateRequired({ key, min, max });

    const zsetKey = this.keyGenerator.set(key, 'zset');
    const args = [zsetKey, min, max];

    if (withScores) {
      args.push('WITHSCORES');
    }

    if (limit) {
      args.push('LIMIT', limit.offset, limit.count);
    }

    const result = await this.execute<string[]>('zrangebyscore', ...args);

    if (withScores) {
      const scoredMembers: ScoredMember[] = [];
      for (let i = 0; i < result.length; i += 2) {
        const member = result[i];
        const scoreStr = result[i + 1];
        if (member && scoreStr) {
          scoredMembers.push({
            member,
            score: parseFloat(scoreStr),
          });
        }
      }
      return scoredMembers;
    }

    return result;
  }

  /**
   * 获取有序集合大小
   */
  async sizeScored(key: string): Promise<number> {
    this.validateRequired({ key });

    const zsetKey = this.keyGenerator.set(key, 'zset');
    return this.execute<number>('zcard', zsetKey);
  }

  /**
   * 按分数范围计数
   */
  async countByScore(key: string, min: number | string, max: number | string): Promise<number> {
    this.validateRequired({ key, min, max });

    const zsetKey = this.keyGenerator.set(key, 'zset');
    return this.execute<number>('zcount', zsetKey, min, max);
  }

  /**
   * 移除按排名范围
   */
  async removeRangeByRank(key: string, start: number, stop: number): Promise<number> {
    this.validateRequired({ key });
    this.validateNumber(start, 'start');
    this.validateNumber(stop, 'stop');

    const zsetKey = this.keyGenerator.set(key, 'zset');
    return this.execute<number>('zremrangebyrank', zsetKey, start, stop);
  }

  /**
   * 移除按分数范围
   */
  async removeRangeByScore(
    key: string,
    min: number | string,
    max: number | string
  ): Promise<number> {
    this.validateRequired({ key, min, max });

    const zsetKey = this.keyGenerator.set(key, 'zset');
    return this.execute<number>('zremrangebyscore', zsetKey, min, max);
  }

  /**
   * 获取集合统计信息
   */
  async getStats(key: string, type: 'set' | 'zset' = 'set'): Promise<SetStats> {
    this.validateRequired({ key });

    const setKey = this.keyGenerator.set(key, type);
    const size = await this.execute<number>(type === 'set' ? 'scard' : 'zcard', setKey);

    return {
      size,
      type,
      memoryUsage: undefined, // 可以通过MEMORY USAGE命令获取
    };
  }

  /**
   * 清空集合
   */
  async clear(key: string, type: 'set' | 'zset' = 'set'): Promise<void> {
    this.validateRequired({ key });

    const setKey = this.keyGenerator.set(key, type);
    await this.deleteKeys(setKey);
  }
}
